package org.easy.wechat;

import com.alibaba.fastjson.JSON;
import org.apache.http.Consts;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpRequestBase;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.*;

/**
 * apache http 通用工具类
 */
public class HttpUtil {
    private static final CloseableHttpClient httpclient = HttpClients.createDefault();


    /**
     * 添加请求头
     *
     * @param httpget httpget
     * @param headers 头
     */
    private static void addHeader(HttpRequestBase httpget, Map<String, String> headers) {
        if (headers == null) {
            return;
        }
        for (Map.Entry<String, String> e : headers.entrySet()) {
            httpget.addHeader(e.getKey(), e.getValue());
        }
    }

    /**
     * 添加表单身体
     *
     * @param httppost httppost
     * @param body     身体
     */
    private static void addFormBody(HttpPost httppost, Map<String, String> body) {
        if (body == null) {
            return;
        }
        List<NameValuePair> formParams = new ArrayList<>();
        for (Map.Entry<String, String> entry : body.entrySet()) {
            formParams.add(new BasicNameValuePair(entry.getKey(), entry.getValue()));
        }
        httppost.setEntity(new UrlEncodedFormEntity(formParams, Consts.UTF_8));
    }

    /**
     * 发送HttpGet请求
     *
     * @param url
     * @return
     */
    public static String sendGet(String url, Map<String, String> headers, Map<String, String> querys) {
        if (headers == null) {
            headers = new HashMap<>();
        }

        if (querys == null) {
            querys = new HashMap<>();
        }

        HttpGet httpget = new HttpGet(buildUrl(url, querys));

        addHeader(httpget, headers);
        try (CloseableHttpResponse response = httpclient.execute(httpget)) {
            HttpEntity entity = response.getEntity();
            if (entity != null) {
                return EntityUtils.toString(entity);
            }
        } catch (IOException e1) {
            e1.printStackTrace();
        }

        return null;
    }


    public static String buildUrl(String url, Map<String, String> params) {
        if (params == null || params.isEmpty()) {
            return null;
        }

        StringBuilder paramString = new StringBuilder(url + "?");
        boolean first = true;
        for (Map.Entry<String, String> p : params.entrySet()) {
            String key = p.getKey();
            String value = p.getValue();

            if (!first) {
                paramString.append("&");
            }

            // Urlencode each request parameter
            try {
                paramString.append(URLEncoder.encode(key, "utf-8"));

                if (value != null) {
                    paramString.append("=").append(URLEncoder.encode(value, "utf-8"));
                }
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            }

            first = false;
        }

        return paramString.toString();
    }


    /**
     * 发送HttpPost请求，参数为map
     *
     * @param url
     * @param t
     * @return
     */
    public static <T> String postForm(String url, Map<String, String> headers, T t) {
        Map<String, Object> stringObjectMap = JSON.parseObject(JSON.toJSONString(t));
        Map<String, String> body = new HashMap<>();
        for (Map.Entry<String, Object> stringObjectEntry : stringObjectMap.entrySet()) {
            if (stringObjectEntry.getKey() == null || stringObjectEntry.getValue() == null) {
                continue;
            }
            body.put(stringObjectEntry.getKey(), stringObjectEntry.getValue().toString());
        }
        return postForm(url, headers, body);
    }

    public static String postJson(String url, Map<String, String> headers, Object object) {
        if (headers == null) {
            headers = new HashMap<>();
        }

        HttpPost httpPost = new HttpPost(url);
        addHeader(httpPost, headers);

        httpPost.setEntity(new StringEntity(JSON.toJSONString(object), StandardCharsets.UTF_8)); // post方法中，加入json数据
        httpPost.setHeader("Content-Type", "application/json");
        try (CloseableHttpResponse response = httpclient.execute(httpPost)) {
            HttpEntity entity = response.getEntity();
            if (entity == null) {
                return null;
            }
            return EntityUtils.toString(entity);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * post 表单发送请求
     *
     * @param url     url
     * @param headers 头
     * @param body    身体
     * @return {@link String}
     */
    public static String postForm(String url, Map<String, String> headers, Map<String, String> body) {
        if (headers == null) {
            headers = new HashMap<>();
        }
        if (body == null) {
            body = new HashMap<>();
        }

        HttpPost httppost = new HttpPost(url);
        addHeader(httppost, headers);

        addFormBody(httppost, body);
        httppost.setHeader("Content-Type", "application/x-www-form-urlencoded");

        try (CloseableHttpResponse response = httpclient.execute(httppost)) {
            HttpEntity entity = response.getEntity();
            if (entity == null) {
                return null;
            }
            return EntityUtils.toString(entity);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }


    /**
     * post json get迷你文件
     *
     * @param url     url
     * @param headers 头
     * @param object  object
     * @return {@link String}  BASE64编码的文件
     */
    public static String postJsonBase64MiniFile(String url, Map<String, String> headers, Object object) {
        if (headers == null) {
            headers = new HashMap<>();
        }

        try {
            HttpPost httpPost = new HttpPost(url);
            addHeader(httpPost, headers);
            httpPost.setEntity(new StringEntity(JSON.toJSONString(object), StandardCharsets.UTF_8));
            httpPost.setHeader("Content-Type", "application/json");
            HttpResponse response = httpclient.execute(httpPost);
            if (response != null) {
                HttpEntity resEntity = response.getEntity();
                if (resEntity == null) {
                    return null;
                }

                byte[] bytes = EntityUtils.toByteArray(response.getEntity());
                Base64.Encoder encoder = Base64.getEncoder();
                return encoder.encodeToString(bytes);
            }
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        return null;
    }


}


